package snafu.implementation.agents;

import java.awt.Color;
import java.util.ArrayList;
import java.util.List;

import snafu.framework.actions.AbstractAction;
import snafu.framework.actions.AbstractReaction;
import snafu.framework.agents.AgentBrain;
import snafu.framework.agents.AgentState;
import snafu.framework.agents.AgentStateItself;
import snafu.framework.objects.WorldObject;
import snafu.framework.view.Access;
import snafu.framework.worlds.Position;
import snafu.framework.worlds.Tile;
import snafu.framework.worlds.WorldMap;
import snafu.implementation.actions.collect.CollectIntention;
import snafu.implementation.actions.collect.CollectIntentionItself;
import snafu.implementation.actions.walk.WalkIntention;
import snafu.implementation.actions.walk.WalkIntentionItself;
import snafu.implementation.objects.banana.Banana;
import snafu.implementation.states.literals.color.ColorLiteralItself;
import snafu.implementation.states.literals.depth.DepthLiteralItself;
import snafu.implementation.states.literals.position.PositionLiteral;

public class HungryApeAgent extends AgentBrain {
	@Override
	public AgentStateItself getInitialState() {
		// create initial state
		AgentStateItself state = new AgentStateItself();
		
		// literals
		state.setLiteral(new ColorLiteralItself(new Color(161, 63, 14), Access.PUBLIC));
		state.setLiteral(new DepthLiteralItself(2, Access.PUBLIC));
		
		// intentions
		state.setIntention(new WalkIntentionItself(Access.PRIVATE));
		state.setIntention(new CollectIntentionItself(Access.PRIVATE));
//		state.setIntention(new DropIntentionItself(Access.PRIVATE));

		return state;
	}

	@Override
	public AbstractAction act(WorldMap perception, AgentState state) {
		
		Position currentPosition = state.getLiteral(PositionLiteral.class);

		// collect item
		CollectIntention collectIntention = state.getIntention(CollectIntention.class);
		if (collectIntention != null) {
			for (WorldObject object : perception.get(currentPosition).getWorldObjects()) {
				if (collectIntention.isApplicable(perception, state, object)) {
					return collectIntention.createAction(object);
				}
			}
		}
		
		// create possible walk actions
		List<AbstractAction> bananaActions = new ArrayList<AbstractAction>();
		List<AbstractAction> walkActions = new ArrayList<AbstractAction>();
		// check every neighbor tile for possible actions
		WalkIntention walkIntention = state.getIntention(WalkIntention.class);
		if (walkIntention != null) {
			for (Tile tile : perception.getNeighborhood(currentPosition)) {
				WorldObject walkable = null;
				boolean banana = false;
				// check all objects
				for (WorldObject object : tile.getWorldObjects()) {
					// walkable test
					if (walkIntention.isApplicable(perception, state, object)) {
						walkable = object;
					}
					// banana test	
					if (Banana.class.isAssignableFrom(object.getClass())) {
						banana = true;
					}
				}
				// create action depending on objects
				if (walkable != null) {
					AbstractAction walkAction = walkIntention.createAction(walkable); 
					walkActions.add(walkAction);
					
					if (banana) {
						bananaActions.add(walkAction);
					}
				}
			}
		}
		
		// choose walk direction, prefer bananas
		if (bananaActions.size() > 0) {
			int index = (int) (Math.random() * bananaActions.size());
			return bananaActions.get(index);
		}
		if (walkActions.size() > 0) {
			int index = (int) (Math.random() * walkActions.size());
			return walkActions.get(index);
		}
		
		// nothing to do
		return null;
	}
	
	@Override
	public AbstractReaction react(AbstractAction action) {
		return null;
	}
	
	@Override
	public String output() {
		return "HungryApeAgent";
	}
}
